home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / Random.java < prev    next >
Text File  |  1998-09-22  |  7KB  |  200 lines

  1. /*
  2.  * @(#)Random.java    1.17 98/07/01
  3.  *
  4.  * Copyright 1995-1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  * 
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14.  
  15. package java.util;
  16.  
  17. /**
  18.  * An instance of this class is used to generate a stream of 
  19.  * pseudorandom numbers. The class uses a 48-bit seed, which is 
  20.  * modified using a linear congruential formula. (See Donald Knuth, 
  21.  * <i>The Art of Computer Programming, Volume 2</i>, Section 3.2.1.) 
  22.  * <p>
  23.  * If two instances of <code>Random</code> are created with the same 
  24.  * seed, and the same sequence of method calls is made for each, they 
  25.  * will generate and return identical sequences of numbers. 
  26.  * <p>
  27.  * Many applications will find the <code>random</code> method in 
  28.  * class <code>Math</code> simpler to use.
  29.  *
  30.  * @author  Frank Yellin
  31.  * @version 1.17, 07/01/98
  32.  * @see     java.lang.Math#random()
  33.  * @since   JDK1.0
  34.  */
  35. public
  36. class Random implements java.io.Serializable {
  37.     private long seed;
  38.     private final static long multiplier = 0x5DEECE66DL;
  39.     private final static long addend = 0xBL;
  40.     private final static long mask = (1L << 48) - 1;
  41.  
  42.     /** 
  43.      * Creates a new random number generator. Its seed is initialized to 
  44.      * a value based on the current time. 
  45.      *
  46.      * @see     java.lang.System#currentTimeMillis()
  47.      * @since   JDK1.0
  48.      */
  49.     public Random() { this(System.currentTimeMillis()); }
  50.  
  51.     /** 
  52.      * Creates a new random number generator using a single 
  53.      * <code>long</code> seed. 
  54.      *
  55.      * @param   seed   the initial seed.
  56.      * @see     java.util.Random#setSeed(long)
  57.      * @since   JDK1.0
  58.      */
  59.     public Random(long seed) {
  60.         setSeed(seed);
  61.     }
  62.  
  63.     /**
  64.      * Sets the seed of this random number generator using a single 
  65.      * <code>long</code> seed. 
  66.      *
  67.      * @param   seed   the initial seed.
  68.      * @since   JDK1.0
  69.      */
  70.     synchronized public void setSeed(long seed) {
  71.         this.seed = (seed ^ multiplier) & mask;
  72.         haveNextNextGaussian = false;
  73.     }
  74.  
  75.     /**
  76.      * Generates the next pseudorandom number. Subclass should
  77.      * override this, as this is used by all other methods.
  78.      *
  79.      * @param   bits random bits
  80.      * @return  the next pseudorandom value from this random number generator's sequence.
  81.      * @since   JDK1.1
  82.      */
  83.     synchronized protected int next(int bits) {
  84.         long nextseed = (seed * multiplier + addend) & mask;
  85.         seed = nextseed;
  86.         return (int)(nextseed >>> (48 - bits));
  87.     }
  88.  
  89.     private static final int BITS_PER_BYTE = 8;
  90.     private static final int BYTES_PER_INT = 4;
  91.  
  92.     /**
  93.      * Generates a user specified number of random bytes.
  94.      *
  95.      * @since   JDK1.1
  96.      */
  97.     public void nextBytes(byte[] bytes) {
  98.     int numRequested = bytes.length;
  99.  
  100.     int numGot = 0, rnd = 0;
  101.  
  102.     while (true) {
  103.         for (int i = 0; i < BYTES_PER_INT; i++) {
  104.         if (numGot == numRequested)
  105.             return;
  106.  
  107.         rnd = (i==0 ? next(BITS_PER_BYTE * BYTES_PER_INT)
  108.                     : rnd >> BITS_PER_BYTE);
  109.         bytes[numGot++] = (byte)rnd;
  110.         }
  111.     }
  112.     }
  113.  
  114.     /**
  115.      * Returns the next pseudorandom, uniformly distributed <code>int</code>
  116.      * value from this random number generator's sequence.
  117.      *
  118.      * @return  the next pseudorandom, uniformly distributed <code>int</code>
  119.      *          value from this random number generator's sequence.
  120.      * @since   JDK1.0
  121.      */
  122.     public int nextInt() {  return next(32); }
  123.  
  124.     /**
  125.      * Returns the next pseudorandom, uniformly distributed <code>long</code>
  126.      * value from this random number generator's sequence.
  127.      *
  128.      * @return  the next pseudorandom, uniformly distributed <code>long</code>
  129.      *          value from this random number generator's sequence.
  130.      * @since   JDK1.0
  131.      */
  132.     public long nextLong() {
  133.         // it's okay that the bottom word remains signed.
  134.         return ((long)(next(32)) << 32) + next(32);
  135.     }
  136.  
  137.     /**
  138.      * Returns the next pseudorandom, uniformly distributed <code>float</code>
  139.      * value between <code>0.0</code> and <code>1.0</code> from this random
  140.      * number generator's sequence.
  141.      *
  142.      * @return  the next pseudorandom, uniformly distributed <code>float</code>
  143.      *          value between <code>0.0</code> and <code>1.0</code> from this
  144.      *          random number generator's sequence.
  145.      * @since   JDK1.0
  146.      */
  147.     public float nextFloat() {
  148.         int i = next(24);
  149.         return i / ((float)(1 << 24));
  150.     }
  151.  
  152.     /**
  153.      * Returns the next pseudorandom, uniformly distributed 
  154.      * <code>double</code> value between <code>0.0</code> and
  155.      * <code>1.0</code> from this random number generator's sequence.
  156.      *
  157.      * @return  the next pseudorandom, uniformly distributed 
  158.      *          <code>double</code> value between <code>0.0</code> and
  159.      *          <code>1.0</code> from this random number generator's sequence.
  160.      * @since   JDK1.0
  161.      */
  162.     public double nextDouble() {
  163.         long l = ((long)(next(26)) << 27) + next(27);
  164.         return l / (double)(1L << 53);
  165.     }
  166.  
  167.     private double nextNextGaussian;
  168.     private boolean haveNextNextGaussian = false;
  169.  
  170.     /**
  171.      * Returns the next pseudorandom, Gaussian ("normally") distributed
  172.      * <code>double</code> value with mean <code>0.0</code> and standard
  173.      * deviation <code>1.0</code> from this random number generator's sequence.
  174.      *
  175.      * @return  the next pseudorandom, Gaussian ("normally") distributed
  176.      *          <code>double</code> value with mean <code>0.0</code> and
  177.      *          standard deviation <code>1.0</code> from this random number
  178.      *          generator's sequence.
  179.      * @since   JDK1.0
  180.      */
  181.     synchronized public double nextGaussian() {
  182.         // See Knuth, ACP, Section 3.4.1 Algorithm C.
  183.         if (haveNextNextGaussian) {
  184.             haveNextNextGaussian = false;
  185.             return nextNextGaussian;
  186.         } else {
  187.             double v1, v2, s;
  188.             do { 
  189.                 v1 = 2 * nextDouble() - 1; // between -1 and 1
  190.                 v2 = 2 * nextDouble() - 1; // between -1 and 1 
  191.                 s = v1 * v1 + v2 * v2;
  192.             } while (s >= 1);
  193.             double multiplier = Math.sqrt(-2 * Math.log(s)/s);
  194.             nextNextGaussian = v2 * multiplier;
  195.             haveNextNextGaussian = true;
  196.             return v1 * multiplier;
  197.         }
  198.     }
  199. }     
  200.